public class MyBlockingQueue {
    //定义一个数组来存放数据，具体的容量由构造方法的参数决定
    private Integer[] elementData;
    //定义头尾下标
    private volatile int head = 0;
    private volatile int tail = 0;
    //定义数组的元素个数
    private volatile int size = 0;

    public MyBlockingQueue(int capacity){
        if (capacity<=0){
            throw new RuntimeException("队列容量必须大于0.");
        }
        elementData = new Integer[capacity];  //创建一个整数类型的数组用于存储元素
    }

    //插入数据的方法
    public void put(Integer value)throws InterruptedException{
        synchronized (this){
            //判断队列是否为满
            while (size>=elementData.length){
                //阻塞队列在队列满的时候就应该阻塞等待
                this.wait();  //等待
            }
            //插入数据的过程在队尾插入元素
            elementData[tail] = value;
            tail++;  //移动队尾下标
            //处理队尾下标
            if (tail>=elementData.length){
                tail = 0;  //回到数据头
            }
            size++;
            this.notifyAll();  //唤醒所有的阻塞线程
        }
    }


    //获取数据的方法
    public synchronized Integer take()throws InterruptedException{
        //判断线程是否为空
        while (size == 0){
            this.wait();
        }
        //出栈的过程，获取出队元素
        Integer value = elementData[head];
        head++;
        //处理队头下标
        if (head>=elementData.length){
            head =0;  //回到数据头
        }
        //处理数组中的元素个数
        size--;
        this.notifyAll();
        return value;
    }
}
